/**
 * 验证工具函数
 */

import type { ValidationRule, ValidationResult, ValidatorOptions } from './types'

/**
 * 验证邮箱地址
 * @param email 邮箱地址
 * @param options 验证选项
 * @returns 是否为有效邮箱
 */
export function isEmail(email: string, options: ValidatorOptions = {}): boolean {
  const { allowEmpty = false, trim = true } = options
  
  const value = trim ? email.trim() : email
  
  if (!value && allowEmpty) {
    return true
  }
  
  if (!value) {
    return false
  }
  
  const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
  return emailRegex.test(value)
}

/**
 * 验证手机号码（中国大陆）
 * @param phone 手机号码
 * @param options 验证选项
 * @returns 是否为有效手机号
 */
export function isPhone(phone: string, options: ValidatorOptions = {}): boolean {
  const { allowEmpty = false, trim = true } = options
  
  const value = trim ? phone.trim() : phone
  
  if (!value && allowEmpty) {
    return true
  }
  
  if (!value) {
    return false
  }
  
  const phoneRegex = /^1[3-9]\d{9}$/
  return phoneRegex.test(value)
}

/**
 * 验证身份证号码（中国大陆）
 * @param idCard 身份证号码
 * @param options 验证选项
 * @returns 是否为有效身份证号
 */
export function isIdCard(idCard: string, options: ValidatorOptions = {}): boolean {
  const { allowEmpty = false, trim = true } = options
  
  const value = trim ? idCard.trim() : idCard
  
  if (!value && allowEmpty) {
    return true
  }
  
  if (!value) {
    return false
  }
  
  // 18位身份证号码正则
  const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
  
  if (!idCardRegex.test(value)) {
    return false
  }
  
  // 验证校验码
  return validateIdCardChecksum(value)
}

/**
 * 验证身份证校验码
 */
function validateIdCardChecksum(idCard: string): boolean {
  const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
  const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
  
  let sum = 0
  for (let i = 0; i < 17; i++) {
    sum += parseInt(idCard[i]) * weights[i]
  }
  
  const expectedCheckCode = checkCodes[sum % 11]
  const actualCheckCode = idCard[17].toUpperCase()
  
  return expectedCheckCode === actualCheckCode
}

/**
 * 验证URL地址
 * @param url URL地址
 * @param options 验证选项
 * @returns 是否为有效URL
 */
export function isUrl(url: string, options: ValidatorOptions = {}): boolean {
  const { allowEmpty = false, trim = true } = options
  
  const value = trim ? url.trim() : url
  
  if (!value && allowEmpty) {
    return true
  }
  
  if (!value) {
    return false
  }
  
  try {
    new URL(value)
    return true
  } catch {
    return false
  }
}

/**
 * 验证IP地址（IPv4）
 * @param ip IP地址
 * @param options 验证选项
 * @returns 是否为有效IP地址
 */
export function isIPv4(ip: string, options: ValidatorOptions = {}): boolean {
  const { allowEmpty = false, trim = true } = options
  
  const value = trim ? ip.trim() : ip
  
  if (!value && allowEmpty) {
    return true
  }
  
  if (!value) {
    return false
  }
  
  const ipRegex = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
  return ipRegex.test(value)
}

/**
 * 验证数字
 * @param value 待验证值
 * @param options 验证选项
 * @returns 是否为数字
 */
export function isNumber(value: any, options: ValidatorOptions = {}): boolean {
  const { allowEmpty = false } = options
  
  if (value === '' || value === null || value === undefined) {
    return allowEmpty
  }
  
  return !isNaN(Number(value)) && isFinite(Number(value))
}

/**
 * 验证整数
 * @param value 待验证值
 * @param options 验证选项
 * @returns 是否为整数
 */
export function isInteger(value: any, options: ValidatorOptions = {}): boolean {
  const { allowEmpty = false } = options
  
  if (value === '' || value === null || value === undefined) {
    return allowEmpty
  }
  
  return Number.isInteger(Number(value))
}

/**
 * 验证正整数
 * @param value 待验证值
 * @param options 验证选项
 * @returns 是否为正整数
 */
export function isPositiveInteger(value: any, options: ValidatorOptions = {}): boolean {
  if (!isInteger(value, options)) {
    return false
  }
  
  return Number(value) > 0
}

/**
 * 验证中文姓名
 * @param name 姓名
 * @param options 验证选项
 * @returns 是否为有效中文姓名
 */
export function isChineseName(name: string, options: ValidatorOptions = {}): boolean {
  const { allowEmpty = false, trim = true } = options
  
  const value = trim ? name.trim() : name
  
  if (!value && allowEmpty) {
    return true
  }
  
  if (!value) {
    return false
  }
  
  const chineseNameRegex = /^[\u4e00-\u9fa5]{2,20}$/
  return chineseNameRegex.test(value)
}

/**
 * 验证密码强度
 * @param password 密码
 * @param minLength 最小长度，默认为8
 * @returns 密码强度评级（weak, medium, strong）
 */
export function getPasswordStrength(password: string, minLength: number = 8): 'weak' | 'medium' | 'strong' {
  if (!password || password.length < minLength) {
    return 'weak'
  }
  
  let score = 0
  
  // 长度得分
  if (password.length >= minLength) score += 1
  if (password.length >= 12) score += 1
  
  // 字符类型得分
  if (/[a-z]/.test(password)) score += 1  // 小写字母
  if (/[A-Z]/.test(password)) score += 1  // 大写字母
  if (/[0-9]/.test(password)) score += 1  // 数字
  if (/[^a-zA-Z0-9]/.test(password)) score += 1  // 特殊字符
  
  if (score <= 2) return 'weak'
  if (score <= 4) return 'medium'
  return 'strong'
}

/**
 * 通用验证器
 * @param value 待验证值
 * @param rules 验证规则
 * @returns 验证结果
 */
export function validate(value: any, rules: ValidationRule[]): ValidationResult {
  const errors: string[] = []
  
  for (const rule of rules) {
    const { required, pattern, min, max, minLength, maxLength, message, validator } = rule
    
    // 必填验证
    if (required && (value === null || value === undefined || value === '')) {
      errors.push(message || '此字段为必填项')
      continue
    }
    
    // 如果值为空且不是必填，跳过其他验证
    if (!required && (value === null || value === undefined || value === '')) {
      continue
    }
    
    // 正则验证
    if (pattern && !pattern.test(String(value))) {
      errors.push(message || '格式不正确')
    }
    
    // 数值范围验证
    if (typeof value === 'number') {
      if (min !== undefined && value < min) {
        errors.push(message || `值不能小于 ${min}`)
      }
      if (max !== undefined && value > max) {
        errors.push(message || `值不能大于 ${max}`)
      }
    }
    
    // 字符串长度验证
    if (typeof value === 'string') {
      if (minLength !== undefined && value.length < minLength) {
        errors.push(message || `长度不能少于 ${minLength} 个字符`)
      }
      if (maxLength !== undefined && value.length > maxLength) {
        errors.push(message || `长度不能超过 ${maxLength} 个字符`)
      }
    }
    
    // 自定义验证器
    if (validator) {
      const result = validator(value)
      if (result === false) {
        errors.push(message || '验证失败')
      } else if (typeof result === 'string') {
        errors.push(result)
      }
    }
  }
  
  return {
    valid: errors.length === 0,
    message: errors[0],
    errors
  }
}